<script setup lang="ts">
import type { EChartsOption } from 'echarts'
import echarts from '@/plugins/echarts/index'
import { debounce } from 'lodash-es'
// import 'echarts-wordcloud'
import {
  computed,
  type PropType,
  ref,
  unref,
  watch,
  onMounted,
  onBeforeUnmount,
  onActivated,
  nextTick
} from 'vue'
import { resizeObserver as vResizeObserver } from './utils/directive'

const emit = defineEmits<{
  resize: [
    {
      width: number
      height: number
    }
  ]
}>()



const props = defineProps({
  options: {
    type: Object as PropType<EChartsOption>,
    required: true
  },
  width: {
    type: [Number, String] as PropType<number | string>,
    default: '100%'
  },
  height: {
    type: [Number, String] as PropType<number | string>,
    default: '500px'
  }
})

const theme = computed(() => {
  // const echartTheme: boolean | string = unref(isDark) ? true : 'auto'

  return 'auto'
})

const options = computed(() => {
  return Object.assign(props.options, {
    darkMode: unref(theme)
  })
})

const elRef = ref<any>()

let echartRef: echarts.ECharts | null = null

const styles = computed(() => {
  const width = typeof props.width === 'string' ? props.width : `${props.width}px`
  const height =  typeof props.height === 'string' ? props.height : `${props.height}px`

  return {
    width,
    height,
    background: 'none'
  }
})

let resolveEchartsEl: (value: HTMLDivElement) => void
let resolveEchartsInstance: (value: echarts.ECharts) => void
const getEchartElPromise: Promise<HTMLDivElement> = new Promise((resolve) => {
  resolveEchartsEl = resolve
})
const getEchartInstancePromise: Promise<echarts.ECharts> = new Promise((resolve) => {
  resolveEchartsInstance = resolve
})

defineExpose({
  getEchartEl() {
    return getEchartElPromise
  },
  getEchartInstance() {
    return getEchartInstancePromise
  }
})

const initChart = () => {
  if (unref(elRef) && props.options) {
    echartRef = echarts.init(unref(elRef) as HTMLElement)
    echartRef?.setOption(unref(options))
    resolveEchartsEl(elRef.value as HTMLDivElement)
    resolveEchartsInstance(echartRef as echarts.ECharts)
  }
}

watch(
  () => options.value,
  (options) => {
    if (echartRef) {
      echartRef?.setOption(options)
    }
  },
  {
    deep: true
  }
)

const resizeHandler = debounce((...args) => {
  echartRef?.resize()
  emit('resize', args[0])
}, 100)

onMounted(() => {
  setTimeout(() => {
    initChart()
  }, 0)
})

onBeforeUnmount(() => {
  const canvas = elRef.value?.querySelector('canvas')
  nextTick(() => {
    canvas?.getContext('webgl')?.getExtension('WEBGL_lose_context')?.loseContext()
    echartRef?.dispose()
  })
})

onActivated(() => {
  if (echartRef) {
    echartRef.resize()
  }
})
</script>

<template>
  <div
    ref="elRef"
    :class="[$attrs.class]"
    :style="styles"
    v-resize-observer.debounce="resizeHandler"
  ></div>
</template>
